package gnss_plugs

import (
	"dgo/go-plugs/gnssio"
	"dgo/goutils/gnss"
	"dgo/goutils/utils"
	"time"
)

type GnssRtcmChannel struct {
	Id              string
	rtcmRawBuf      *gnss.Rtcm3RawBuf
	lastRtcmTime    time.Time
	inner_data_comm gnssio.I_Comm
	OnDecodeRtcmBuf func(rtcmRawBuf *gnss.Rtcm3RawBuf, decodeR int)
	OnRtcmRec       func(rtcmBuf []byte, decodeR int, rtcmRec *gnss.GnssRtcmData)
}

func NewGnssRtcmChannel() *GnssRtcmChannel {
	return &GnssRtcmChannel{
		rtcmRawBuf: gnss.NewRtcm32RawBuf(""),
	}
}

func (this *GnssRtcmChannel) SetInnerDataComm(data_comm gnssio.I_Comm) {
	if this.inner_data_comm != data_comm {
		if this.inner_data_comm != nil {
			this.inner_data_comm.RemoveListener(this)
		}
		this.inner_data_comm = data_comm
		this.inner_data_comm.AddListener(this)
	}
}

func (this *GnssRtcmChannel) OnReceive(sender gnssio.I_Comm, buf []byte, l int) {
	this.rtcmRawBuf.OutputWarning = false
	for i := 0; i < l; i++ {
		r := this.rtcmRawBuf.InputBuf(buf[i])
		if r == gnss.RTCM_OK {
			rtcmBuf := this.rtcmRawBuf.GetRtcmMsgBuf()
			this.onRtcmBuf(this.rtcmRawBuf.GetRawBuf(), rtcmBuf)
			if this.OnDecodeRtcmBuf != nil {
				this.OnDecodeRtcmBuf(this.rtcmRawBuf, r)
			}
			this.rtcmRawBuf.Reset()
		} else if r == gnss.RTCM_CRC_FAIL {
			if this.OnDecodeRtcmBuf != nil {
				this.OnDecodeRtcmBuf(this.rtcmRawBuf, r)
			}
			utils.Log.Warnf("[%s]CRC校验失败", this.Id)
			this.rtcmRawBuf.Reset()
		} else if r == -1 {
			if this.rtcmRawBuf.GetSize() > 1 {
				utils.Log.Warnf("[%s]RTCM解码异常", this.Id)
				if this.OnDecodeRtcmBuf != nil {
					this.OnDecodeRtcmBuf(this.rtcmRawBuf, r)
				}
			}
			this.rtcmRawBuf.Reset()
		}
	}
}

func (this *GnssRtcmChannel) OnConnect(sender gnssio.I_Comm) {

}

func (this *GnssRtcmChannel) OnDisconnect(sender gnssio.I_Comm) {

}

/*
*

	rtcmMsgRawBuf :包含了头和CRC
*/
func (this *GnssRtcmChannel) onRtcmBuf(rtcmMsgRawBuf, rtcmBuf []byte) {

	// 解码观测值,
	msm, _ := gnss.DecodeRtcmMsm(rtcmBuf, 0)
	if msm != nil {
		this.lastRtcmTime = msm.Header.DecodeTime(this.lastRtcmTime)
		rtcmRec := gnss.NewGnssRtcmData(int(msm.Header.MsgId), gnss.TYPE_OBS, msm)
		rtcmRec.RtcmTime = this.lastRtcmTime
		rtcmRec.RawBuf = rtcmMsgRawBuf
		rtcmRec.Sys = msm.Sys
		if this.OnRtcmRec != nil {
			this.OnRtcmRec(rtcmBuf, 0, rtcmRec)
		}
		return
	}

	eph, r := gnss.DecodeRtcmEph(rtcmBuf, 0)
	if eph != nil {
		if r == -1 {
			if this.OnRtcmRec != nil {
				this.OnRtcmRec(rtcmBuf, r, nil)
			}
		}
		eph.RefUtcTime = this.lastRtcmTime
		eph.DecodeEphTime()
		rtcmRec := gnss.NewGnssRtcmData(int(eph.MsgId), gnss.TYPE_EPH, eph)
		rtcmRec.RtcmTime = this.lastRtcmTime
		rtcmRec.RawBuf = rtcmMsgRawBuf
		rtcmRec.Sys = eph.Sys
		if this.OnRtcmRec != nil {
			this.OnRtcmRec(rtcmBuf, 0, rtcmRec)
		}
		return
	}

	rtcmRec, _ := gnss.DecodeRtcmPack(rtcmBuf, 0)
	if rtcmRec != nil {
		rtcmRec.RtcmTime = this.lastRtcmTime
		rtcmRec.RawBuf = rtcmMsgRawBuf
		if this.OnRtcmRec != nil {
			this.OnRtcmRec(rtcmBuf, 0, rtcmRec)
		}
		return
	}

	rtcmRec, _ = gnss.DecodeUnkownRtcmPack(rtcmBuf, 0)
	if rtcmRec != nil {
		rtcmRec.RtcmTime = this.lastRtcmTime
		rtcmRec.RawBuf = rtcmMsgRawBuf
		if this.OnRtcmRec != nil {
			this.OnRtcmRec(rtcmBuf, 0, rtcmRec)
		}
		return
	}
}
